/*
 * 代号：凤凰
 * http://www.jphenix.org
 * 2014-06-12
 * V4.0
 */
package com.jphenix.share.lang;

import com.jphenix.share.util.BaseUtil;
import com.jphenix.standard.docs.ClassInfo;
import com.jphenix.standard.lang.ICloneable;

import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 * 解析日期字符串类
 * com.jphenix.share.lang.SDate
 * 
 * 
 * 2018-05-23 增加了设置年份，设置月份，设置天，设置小时，设置分钟，设置秒的方法
 * 2018-05-29 将subtractDateReturnDay,subtractDateReturnHour,subtractDateReturnMinute,subtractDateReturnSecond,subtractDateReturnMillisecond改为静态方法
 * 2018-06-07 修改了setSecond() setMinute() setHour() 方法，超过60值时，不设置为59 而是取与60除后的余数（不做进位，如果需要进位，使用 Apoint 方法）
 * 2018-06-11 增加了获取指定年份月份中的天数 getMonthDays的静态方法
 * 2018-06-16 getMonthLastWeekDay(int week,int month,int year) 获取指定月份，末尾指定周几是几号。比如18年6月的最后一个周五
 *            isLaskWeek() 当前日期所在的星期是否为当月的最后一个星期 （即，下个星期的这个星期几，已经在下个月）
 * 2018-11-21 增加了与当日0点时间做比较
 * 2019-01-25 去掉了传入字符串参数的构造函数，统一用传入Object的构造函数
 * 2019-03-11 增加了获取指定格式日期字符串的方法format()
 * 2019-05-23 增加了返回当天周汉字信息
 * 2019-06-20 增加了cn克隆方法，直接返回SDate类型类实例
 * 2019-09-11 修改了显示毫秒信息方法，增加了天信息
 * 2019-10-14 增加了静态方法millisecondOf，将日期对象转换为毫秒值
 * 2021-07-18 增加了 getYYYY() getYY() getYYYYMM() getYYMM() getYYYYMMDD() getYYMMDD() 方法
 * 
 * @author 刘虻
 * 2006-8-16  11:32:09
 */
@ClassInfo({"2021-07-18 23:46","解析日期字符串类"})
public class SDate implements ICloneable {

	/**
	 dateString 日期字符串
	 */
	protected String dateString;
	/**
	 date 日期对象
	 */
    protected Date date;
	/**
	 isDate 是否是日期格式
	 */
    protected boolean isDate = true;
    /**
    MILLISECONDS_OF_DAY 一天的毫秒数
     */
	private static long MILLISECONDS_OF_DAY = 86400000;
	/**
    MILLISECONDS_OF_HOUR 一小时的毫秒数
     */
	private static long MILLISECONDS_OF_HOUR = 3600000;
	/**
    MILLISECONDS_OF_MINUTE 一分钟的毫秒数
     */
	private static long MILLISECONDS_OF_MINUTE = 60000;
	/**
    MILLISECONDS_OF_SECOND 一秒的毫秒数
     */
	private static long MILLISECONDS_OF_SECOND = 1000;
    
    /**
     * 构造函数 
     * @author 刘虻
     * 2006-8-16 11:35:30
     */
    public SDate() {
        super();
        setDate(new Date());
    }
    
    
    /**
     * 构造函数
     * 2007-2-2下午12:38:59
     */
    public SDate(long milliseconds) {
    	super();
    	setMillisecond(milliseconds);
    }
    
    
    /**
     * 构造函数
     * 2007-8-30下午03:09:59
     */
    public SDate(Object dateString) {
    	super();
    	setDateObject(dateString);
    }
    
    
    /**
     * 设置日期对象
     * @author 刘虻
     * 2007-8-30下午03:10:04
     * @param dateObj 日期对象
     */
    public void setDateObject(Object dateObj) {
    	if (dateObj==null) {
    		setDate(new Date());
    	}else if (dateObj instanceof Date) {
    		setDate((Date)dateObj);
    	}else if (dateObj instanceof SDate) {
    		setDate(((SDate)dateObj).getDate());
    	}else if(dateObj instanceof java.sql.Date) {
    	    setMillisecond(((java.sql.Date)dateObj).getTime());
    	}else if(dateObj instanceof java.sql.Time) {
    	    setMillisecond(((java.sql.Time)dateObj).getTime());
    	}else if(dateObj instanceof java.sql.Timestamp) {
    	    setMillisecond(((java.sql.Timestamp)dateObj).getTime());
    	}else {
    	    //转换为字符串
    	    String dateStr = String.valueOf(dateObj);
    	    if(dateStr.length()<9) {
    	        //yyyymmdd
    	        setDateString(dateStr);
    	    }else {
                //尝试获取毫秒
                long dateLong = 0;
                try {
                    dateLong = new Long(dateStr).longValue();
                }catch(Exception e) {}
                if (dateLong>0) {
                    setMillisecond(dateLong);
                }else if (dateObj!=null) {
                        setDateString(String.valueOf(dateObj));
                }
    	    }
    	}
    }
    
    /**
     * 执行将字符串转为日期
     * @author 刘虻
     * 2006-8-16  11:37:34
     */
    protected void doExcute(String dateFormat) {
        
        isDate = true; //默认是日期格式
        
        //构造默认值
        date = new Date();
        
        try {
            //执行解析
            date = parseFormat(dateString,dateFormat);

            doOut(null); //格式化时间字符串
        }catch(Exception e) {
            isDate = false;
        }
        
    }
    
    
    /**
     * 解析普通的时间字符串
     * @author 刘虻
     * 2007-9-15下午05:18:19
     * @param dateString 时间字符串
     * @return 日历对象
     */
    protected Calendar parseNormalFormat(String dateString) {
    	
    	//构建日历对象
    	Calendar cd = Calendar.getInstance();
    	
    	//清空
    	cd.set(0,0,0,0,0);
    	
    	boolean nullDate = true; //没有设置日期时间
    	
    	//获取日期时间分割点
    	int point = dateString.indexOf(" ");
    	
    	String dateSub = dateString; //日期段
    	if (point>0) {
        	//获取日期段
        	dateSub = dateString.substring(0,point);

        	//获取时间段
        	String timeSub = dateString.substring(point+1);
        	
        	point = timeSub.indexOf(" "); //判断是否有毫秒
        	
        	String mTimeSub = null; //毫秒段
        	if (point>-1) {
        		mTimeSub = timeSub.substring(point+1);
        		timeSub = timeSub.substring(0,point);
        	}
        	//分解时间段
        	String[] sTimeSubs = BaseUtil.split(timeSub,":");
        	if (sTimeSubs!=null) {
        		
        		if (sTimeSubs.length>0) {
        			//设置小时
        			cd.set(Calendar.HOUR_OF_DAY,SInteger.valueOf(sTimeSubs[0]));
        			nullDate = false;
        		}
        		
        		if (sTimeSubs.length>1) {
        			//设置分钟
        			cd.set(Calendar.MINUTE,SInteger.valueOf(sTimeSubs[1]));
        			nullDate = false;
        		}
        		
        		if (sTimeSubs.length>2) {
        			//设置秒
        			cd.set(Calendar.SECOND,SInteger.valueOf(sTimeSubs[2]));
        			nullDate = false;
        		}
        	}
        	if (mTimeSub!=null) {
        		//设置毫秒
        		cd.set(Calendar.MILLISECOND,SInteger.valueOf(mTimeSub));
        	}
    	}        	
    	
    	//分解日期
    	String[] sDateSubs = null;
    	if (dateSub.indexOf("/")>0) {
    		sDateSubs = BaseUtil.split(dateSub,"/");
    	}else {
    		sDateSubs = BaseUtil.split(dateSub,"-");
    	}
    		
    	
    	if (sDateSubs!=null) {
	    	if (sDateSubs.length>0 && sDateSubs[0]!=null) {
	    		if (sDateSubs[0].length()>2) {
	    			cd.set(Calendar.YEAR,SInteger.valueOf(sDateSubs[0]));
	    			nullDate = false;
	    		}else {
	    			//获取2位年
	    			int yearSub = SInteger.valueOf(sDateSubs[0]);
	    			if (yearSub>50) {
	    				cd.set(Calendar.YEAR,1900+yearSub);
	    				nullDate = false;
	    			}else {
	    				cd.set(Calendar.YEAR,2000+yearSub);
	    				nullDate = false;
	    			}
	    		}
	    	}
	    	if (sDateSubs.length>1) {
		    	//获取月份段
		    	int monthSub = SInteger.valueOf(sDateSubs[1]);
		    	if (monthSub>0) {
		    		cd.set(Calendar.MONTH,monthSub-1);
		    		nullDate = false;
		    	}else {
		    		cd.set(Calendar.MONTH,0);
		    		nullDate = false;
		    	}
	    	}

	    	if (sDateSubs.length>2) {
	    		//获取日期分段
	    		cd.set(Calendar.DAY_OF_MONTH,SInteger.valueOf(sDateSubs[2]));
	    		nullDate = false;
	    	}
    	}
    	if (nullDate) {
    		cd.setTime(new Date());
    	}
    	
    	return cd;
    }
    
    
    /**
     * 按照指定时间格式解析时间字符串
     * @author 刘虻
     * 2006-8-30上午11:13:35
     * @param dateString 时间字符串
     * @param dateFormat 指定时间格式
     * @return 解析后的时间对象
     */
    public Date parseFormat(String dateString,String dateFormat) {
    	if(dateString==null || dateString.length()<1) {
    	    return new Date();
    	}
    	int len = dateString.length(); //日期信息长度
    	if (dateFormat==null || dateFormat.length()==0) {
    	    
    	    if(dateString.indexOf("-")>-1) {
    	        if(len>7 && len<11) {
    	            //只有日期
    	            dateFormat = "yyyy-MM-dd";
    	        }else if(len>13 && len<20){
    	            dateFormat = "yyyy-MM-dd HH:mm:ss";
    	        }else {
    	            dateFormat = "yyyy-MM-dd HH:mm:ss SSS";
    	        }
    	    }else if(dateString.indexOf("/")>-1) {
                if(len>7 && len<11) {
                    //只有日期
                    dateFormat = "yyyy/MM/dd";
                }else if(len>13 && len<20){
                    dateFormat = "yyyy/MM/dd HH:mm:ss";
                }else {
                    dateFormat = "yyyy/MM/dd HH:mm:ss SSS";
                }
    	    }else {
    	        if(len>5 && len<9) {
    	            dateFormat = "yyyyMMdd";
    	        }else {
    	            dateFormat = "yyyy-MM-dd HH:mm:ss SSS";
    	            return parseNormalFormat(dateString).getTime();
    	        }
    	    }
    	}
        //日期格式化
        SimpleDateFormat sdmObj = new SimpleDateFormat(dateFormat);
        try {
            return sdmObj.parse(dateString);
        }catch(Exception e) {
            return parseNormalFormat(dateString).getTime();
        }
    }
    
    
    
    
    
    
    
    /**
     * 执行反向解析
     * @author 刘虻
     * @param dateFormat 日期格式
     * 2006-8-17  23:50:37
     */
    protected void doOut(String dateFormat) {
    	dateString = ""; //初始化
    	try {
	        //构造格式解析
	        SimpleDateFormat simpleDateFormat = null;
	        if (dateFormat==null) {
	            //设置默认解析格式
	            simpleDateFormat = 
	                new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	        }else {
	            //设置指定解析格式
	            simpleDateFormat = 
	                new SimpleDateFormat(dateFormat);
	        }
	        //执行解析
	        dateString = simpleDateFormat.format(this.date);
	
	     }catch(Exception e) {}
    }

    

    /**
     * 构造函数 
     * @author 刘虻
     * 2006-8-18 0:06:35
     */
    public SDate(Date date) {
    	super();
    	setDate(date);
    }

    
    /**
     * 返回数据库提交的时间戳类型信息
     * @author 刘虻
     * 2007-7-31下午12:38:37
     * @return 数据库提交的时间戳类型信息
     */
    public Timestamp getTimestamp() {
    	return (new Timestamp(getMillisecond()));
    }


    /**
     * 构造函数 
     * @author 刘虻
     * 2006-8-17 23:53:28
     */
    public SDate(String dateStr, String dateFormat) {
        this.dateString = dateStr;
        doExcute(dateFormat); //执行解析
    }


    /**
     * 设置日期字符串
     * @author 刘虻
     * @param dateObj 日期字符串
     * @return 返回当前类实例
     * 2006-8-17  23:53:37
     */
    public SDate setDate(Object dateObj){
    	if (dateObj!=null) {
	        this.dateString = String.valueOf(dateObj);
	        doExcute(null); //执行解析
    	}
    	return this;
    }
    
    /**
     * 获取毫秒字符串
     * @author 刘虻
     * @return 毫秒字符串
     * 2006-8-18  0:13:26
     */
    public String getMillisecondString() {
    	return String.valueOf(getMillisecond());
    }
    
    
    /**
     * 获取当前日期字符串数字字符串
     * @author 刘虻
     * @return 当前日期字符串数字字符串
     * 2007-3-1  下午06:04:58
     */
    public static String getNowDateNumberString() {
    	return (new SDate()).getDateNumberString();
    }
    
    
    /**
     * 获取日期字符串数字字符串
     * @author 刘虻
     * 2007-12-11上午10:21:40
     * @return 日期字符串数字字符串
     */
    public String getDateNumberString() {
    	return (new StringBuffer(getDateYearString()))
					.append(getMonthString())
					.append(getDayString())
					.toString();
    }
    
    /**
     * 获取紧凑型年月日字符串
     * @author 刘虻
     * 2007-9-5下午12:56:42
     * @param dateStr 源
     * @return 紧凑型年月日字符串
     */
    public static String getThinYMDString(Object dateStr) {
    	return (new SDate(dateStr)).getThinYMDString();
    }
    
    /**
     * 获取两位年紧凑型年月日字符串
     * @author 刘虻
     * 2007-9-5下午12:56:42
     * @param dateStr 源
     * @return 两位年紧凑型年月日字符串
     */
    public static String getShortThinYMDString(Object dateStr) {
    	return (new SDate(dateStr)).getShortThinYMDString();
    }
    
    /**
     * 获取当前日期时间字符串数字字符串
     * @author 刘虻
     * @return 当前日期时间字符串数字字符串
     * 2007-3-1  下午06:06:18
     */
    public static String getNowDateTimeNumberString() {
    	//构造新的日期类
       	SDate sd = new SDate();
    	return (new StringBuffer(sd.getDateYearString()))
    		.append(sd.getMonthString())
    		.append(sd.getDayString())
    		.append(sd.getHourString())
    		.append(sd.getMinuteString())
    		.append(sd.getSecondString())
    		.toString();
    }
    
    
    /**
     * 设置毫秒时间
     * @author 刘虻
     * 2006-9-19下午02:18:19
     * @param millisecondString 毫秒时间
     * @return 返回当前类实例
     */
    public SDate setMillisecondString(String millisecondString) {
    	try {
    		this.date = 
    			new Date((new Long(millisecondString)).longValue());
    	}catch(Exception e) {
    		e.printStackTrace();
    		this.date = new Date();
    	}
    	return this;
    }
    
    /**
     * 设置毫秒时间
     * @author 刘虻
     * 2007-2-2下午12:13:41
     * @param millisecond 毫秒时间
     * @return 返回当前类实例
     */
    public SDate setMillisecond(long millisecond) {
    	try {
    		this.date = new Date(millisecond);
    	}catch(Exception e) {
    		e.printStackTrace();
    		this.date = new Date();
    	}
    	doOut(null); //整理输出时间
    	return this;
    }
    
    /**
     * 判断指定月份的天数
     * @param month 月份
     * @param year 年份（如果是2月份，则需要判断是否为闰年）
     * @return 天数
     * 2014年5月19日
     * @author 马宝刚
     */
    public static int getDaysOfMonth(String month,String year) {
        int monthInt = 0; //整型月份
        try {
            monthInt = Integer.parseInt(month);
        }catch(Exception e) {}
        int yearInt = 0; //年份
        try {
        	yearInt = Integer.parseInt(year);
        }catch(Exception e) {}
        return getDaysOfMonth(monthInt,yearInt);
    }
    
    /**
     * 判断指定月份的天数
     * @param month 月份
     * @param year 年份（如果是2月份，则需要判断是否为闰年）
     * @return 天数
     * 2014年5月19日
     * @author 马宝刚
     */
    public static int getDaysOfMonth(int month,int year) {
    	if(month<1) {
    		month = 1;
    	}else if(month>12) {
    		year += month/12;
    		month = month%12;
    	}
        if(month==2) {
            if(isLeapYear(year)) {
                return 29;
            }
            return 28;
        }
        if(month==1 || month==3 || month==5 || month==7 || month==8 || month==10 || month==12) {
            return 31;
        }
        return 30;
    }
    
    
    /**
     * 判断指定年份是否为闰年
     * 
     * 满足一下两个条件之一的是闰年：
     * 
     * 1.  能被4整除，不能被100整除
     * 2.  能被400整除
     * 
     * @param year
     * @return
     * 2014年5月19日
     * @author 马宝刚
     */
    public static boolean isLeapYear(String year) {
        if(year==null || year.length()<2) {
            return false;
        }
        if(year.length()==2) {
            year = "20"+year;
        }
        int yearInt = 0; //年份数字型
        try {
            yearInt = Integer.parseInt(year);
        }catch(Exception e) {}
        return isLeapYear(yearInt);
    }
    
    /**
     * 判断指定年份是否为闰年
     * 
     * 满足一下两个条件之一的是闰年：
     * 
     * 1.  能被4整除，不能被100整除
     * 2.  能被400整除
     * 
     * @param year
     * @return
     * 2014年5月19日
     * @author 马宝刚
     */
    public static boolean isLeapYear(int year) {
        if(year<1) {
            return false;
        }
        if(year%4>0) {
            return false;
        }
        if(year%100>0) {
            return true;
        }
		return year % 400 <= 0;
	}
    
    

    
    /**
     * 获取毫秒
     * @author 刘虻
     * @return 毫秒
     * 2006-8-18  0:12:49
     */
    public long getMillisecond() {
    	return getDate().getTime();
    }
    
    
    /**
     * 获取当前日期的毫秒
     * @author 刘虻
     * @param dateString 当前日期字符串
     * @return 当前日期的毫秒
     * 2006-8-18  11:03:21
     */
    public static long longValueOf(String dateString) {
    	return (new SDate(dateString)).getMillisecond();
    }
    
    
    /**
     * 获取指定时间的毫秒
     * @author 刘虻
     * 2007-2-27下午04:48:19
     * @param date 指定时间
     * @return 毫秒
     */
    public static long longValueOf(Date date) {
    	return (new SDate(date)).getMillisecond();
    }
    
    /**
     * 获取指定时间的毫秒字符串
     * @author 刘虻
     * 2007-2-27下午04:48:19
     * @param date 指定时间
     * @return 毫秒字符串
     */
    public static String longValueOfString(Date date) {
    	return String.valueOf((new SDate(date)).getMillisecond());
    }
    
    /**
     * 获取秒
     * @author 刘虻
     * @return 秒
     * 2006-8-18  0:11:25
     */
    public int getSecond() {
    	int reInt = 0; //构造返回值
    	try {
    		reInt = (new Integer(getSecondString())).intValue();
    	}catch(Exception e) {}
    	return reInt;
    }
    
    /**
     * 设置秒值
     * @param second 秒值
     * @return 返回当前类实例
     * 2018年5月23日
     * @author MBG
     */
    public SDate setSecond(String second) {
    	int secondInt; //整理后的秒值
    	try {
    		secondInt = Integer.valueOf(second);
    	}catch(Exception e) {
    		secondInt = 0;
    	}
    	return setSecond(secondInt);
    }
    
    
    /**
     * 设置秒值
     * @param second 秒值 并不进位到分钟，如果需要进位，使用setSecondApoint();
     * @return 返回当前类实例
     * 2018年5月23日
     * @author MBG
     */
    public SDate setSecond(int second) {
    	if(second<0) {
    		second = 0;
    	}else if(second>59){
    		second = second%60;
    	}
    	if(second<10) {
    		setDateString(getOnlyDate()+" "+getHourString()+":"+getMinuteString()+":0"+second);
    	}else {
    		setDateString(getOnlyDate()+" "+getHourString()+":"+getMinuteString()+":"+second);
    	}
    	return this;
    }
    
    
    /**
     * 获取秒字符串
     * @author 刘虻
     * @return 秒字符串
     * 2006-8-18  0:10:42
     */
    public String getSecondString() {
    	return getDate("ss");
    }
    
    
    /**
     * 获取分钟
     * @author 刘虻
     * @return 分钟
     * 2006-8-18  0:09:39
     */
    public int getMinute() {
    	int reInt = 0; //构造返回值
    	try {
    		reInt = (new Integer(getMinuteString())).intValue();
    	}catch(Exception e) {}
    	return reInt;
    }
    
    /**
     * 设置分钟值
     * @param minute 分钟值
     * @return 当前类实例
     * 2018年5月23日
     * @author MBG
     */
    public SDate setMinute(String minute) {
    	int minuteInt; //整理后的分钟值
    	try {
    		minuteInt = Integer.valueOf(minute);
    	}catch(Exception e) {
    		minuteInt = 0;
    	}
    	return setMinute(minuteInt);
    }
    
    /**
     * 设置分钟值
     * @param minute 分钟值 并不进位到小时，如果需要进位，用setMinuteApoint();
     * @return 当前类实例
     * 2018年5月23日
     * @author MBG
     */
    public SDate setMinute(int minute) {
    	if(minute<0) {
    		minute = 0;
    	}else if(minute>59) {
    		minute = minute%60;
    	}
    	if(minute<10) {
    		setDateString(getOnlyDate()+" "+getHourString()+":0"+minute+":"+getSecondString());
    	}else {
    		setDateString(getOnlyDate()+" "+getHourString()+":"+minute+":"+getSecondString());
    	}
    	return this;
    }
    
    /**
     * 获取分钟字符串
     * @author 刘虻
     * @return 分钟字符串
     * 2006-8-18  0:09:08
     */
    public String getMinuteString() {
    	return getDate("mm");
    }
    
    /**
     * 获取小时
     * @author 刘虻
     * @return 小时
     * 2006-8-18  0:08:06
     */
    public int getHour() {
    	int reInt = 0; //构造返回值
    	try {
    		reInt = (new Integer(getHourString())).intValue();
    	}catch(Exception e) {}
    	return reInt;
    }
    
    /**
     * 设置小时值
     * @param hour 小时值
     * @return 当前类实例
     * 2018年5月23日
     * @author MBG
     */
    public SDate setHour(String hour) {
    	int hourInt; //整理后的小时值
    	try {
    		hourInt = Integer.valueOf(hour);
    	}catch(Exception e) {
    		hourInt = 0;
    	}
    	return setHour(hourInt);
    }
    
    /**
     * 设置小时值 并不进位到天，如果需要进位，用setHourApoint();
     * @param hour 小时值
     * @return 当前类实例
     * 2018年5月23日
     * @author MBG
     */
    public SDate setHour(int hour) {
    	if(hour<0) {
    		hour = 0;
    	}else if(hour>23) {
    		hour = hour%24;
    	}
    	if(hour<10) {
    		setDateString(getOnlyDate()+" 0"+hour+":"+getMinuteString()+":"+getSecondString());
    	}else {
    		setDateString(getOnlyDate()+" "+hour+":"+getMinuteString()+":"+getSecondString());
    	}
    	return this;
    }
    
    /**
     * 获取小时字符串
     * @author 刘虻
     * @return 小时字符串
     * 2006-8-18  0:07:38
     */
    public String getHourString() {
    	return getDate("HH");
    }
    
    /**
     * 获取天
     * @author 刘虻
     * @return 天
     * 2006-8-18  0:07:11
     */
    public int getDay() {
    	try {
    		return (new Integer(getDayString())).intValue();
    	}catch(Exception e) {}
    	return 0;
    }
    
    /**
     * 设置天值
     * @param day 天值
     * @return 返回当前类实例
     * 2018年5月23日
     * @author MBG
     */
    public SDate setDay(String day) {
    	int dayInt; //整理后的天值
    	try {
    		dayInt = Integer.valueOf(day);
    	}catch(Exception e) {
    		dayInt = 1;
    	}
    	return setDay(dayInt);
    }
    
    
    /**
     * 设置天值
     * @param day 天值 并不进位到月份（如果需要进位到月份，用setDayApoint();
     * @return 返回当前类实例
     * 2018年5月23日
     * @author MBG
     */
    public SDate setDay(int day) {
    	if(day<1) {
    		day = 1;
    	}else if(day>getThisMonthDays()) {
    		int month = getMonth();
    		int year  = getYear();
    		int mDay  = getMonthDays(month,year); //当前月份的天数
    		while(day>mDay) {
    			day = day-mDay;
    			if(month==12) {
    				year++;
    				month = 1;
    			}else {
    				month++;
    			}
    			mDay = getMonthDays(month,year);
    		}
    	}
    	if(day<10) {
    		setDateString(getYearString()+"-"+getMonthString()+"-0"+day+" "+getOnlyTime());
    	}else {
    		setDateString(getYearString()+"-"+getMonthString()+"-"+day+" "+getOnlyTime());
    	}
    	return this;
    }
    
    /**
     * 计算当前日期累加天数后，过了几个月
     * @param day 累加天数
     * @return 过了几个月
     * 2018年6月11日
     * @author MBG
     */
    public int calcMonth(int day) {
    	return calcMonth(getDay()+day,getMonth(),getYear());
    }
    
    /**
     * 计算从指定月份头一天起，累加指定天数，期间过了多少个月
     * @param calcDay   需要累加的天数
     * @param month     指定月份
     * @param year      指定年份
     * @return          期间过了多少个月
     * 2018年6月12日
     * @author MBG
     */
    public static int calcMonth(int calcDay,int month,int year) {
    	if(calcDay<1) {
    		return 0;
    	}
    	int mDay     = getMonthDays(month,year); //当前月份共多少天
    	int resMonth = 0;                        //累计月份
    	if(calcDay>mDay) {
    		resMonth++;
    		calcDay -= mDay;
    		if(month==12) {
    			year++;
    			month = 1;
    		}else {
    			month++;
    		}
    		mDay = getMonthDays(month,year);
    		while(calcDay>=mDay) {
    			resMonth++;
    			calcDay -= mDay;
        		if(month==12) {
        			year++;
        			month = 1;
        		}else {
        			month++;
        		}
        		mDay = getMonthDays(month,year);
    		}
    		return resMonth;
    	}
    	return 0;
    }
    
    
    /**
     * 返回指定月份的天数
     * @param month 指定月份
     * @param year  指定年份
     * @return 天数
     * 2018年6月11日
     * @author MBG
     */
    public static int getMonthDays(int month,int year) {
    	if(month<1) {
    		month = 1;
    	}else if(month>12) {
    		month = 12;
    	}
    	int day;                 //返回当前月份的天数
		if(month==1 || month==3 || month==5 || month==7 || month==8 || month==10 || month==12) {
			day = 31;
		}else if(month==2) {
			if(year%4==0) {
				day = 29;
			}else {
				day = 28;
			}
		}else {
			day = 30;
		}
		return day;
    
    }
    
    /**
     * 返回当前月份的天数
     * @return 当前月份的天数
     * 2018年6月11日
     * @author MBG
     */
    public int getThisMonthDays() {
    	return getMonthDays(getMonth(),getYear());
    }
    
    
    /**
     * 返回天字符串
     * @author 刘虻
     * @return 天字符串
     * 2006-8-18  0:05:59
     */
    public String getDayString() {
    	return getDate("dd");
    }
    
    /**
     * 返回月份数字
     * @author 刘虻
     * @return 月份数字
     * 2006-8-18  0:05:33
     */
    public int getMonth() {
    	try {
    		return (new Integer(getMonthString())).intValue();
    	}catch(Exception e) {}
    	return 0;
    }
    
    /**
     * 设置指定月份值
     * @param month 月份值
     * @return 当前类实例
     * 2018年5月23日
     * @author MBG
     */
    public SDate setMonth(String month) {
    	int monthInt; //整理后的月份值
    	try {
    		monthInt = Integer.valueOf(month);
    	}catch(Exception e) {
    		monthInt = 1;
    	}
    	return setMonth(monthInt);
    }
    
    /**
     * 设置指定月份值
     * @param month 月份值
     * @return 当前类实例
     * 2018年5月23日
     * @author MBG
     */
    public SDate setMonth(int month) {
    	if(month<1) {
    		month = 1;
    	}else if(month>12) {
    		month = month%12;
    	}
    	if(isLastDayOfMonth()) {
    		int year = getYear(); //当前年份
    		month++;
    		if(month>12) {
    			year++;
    			month=1;
    		}
        	if(month<10) {
        		setDateString(year+"-0"+month+"-01 "+getOnlyTime());
        	}else {
        		setDateString(year+"-"+month+"-01 "+getOnlyTime());
        	}
        	setDayApoint(-1);
    	}else {
        	if(month<10) {
        		setDateString(getYearString()+"-0"+month+"-"+getDayString()+" "+getOnlyTime());
        	}else {
        		setDateString(getYearString()+"-"+month+"-"+getDayString()+" "+getOnlyTime());
        	}
    	}
    	return this;
    }
    
    /**
     * 当日是否为本月最后一天
     * @return 当日是否为本月最后一天
     * 2018年6月23日
     * @author MBG
     */
    public boolean isLastDayOfMonth() {
		return getDay() >= getThisMonthDays();
	}
    
    
    
    /**
     * 返回月份字符串
     * @author 刘虻
     * @return 月份字符串
     * 2006-8-18  0:04:49
     */
    public String getMonthString() {
    	return getDate("MM");
    }
    
    /**
     * 返回当前年
     * @author 刘虻
     * 2008-7-2下午12:03:38
     * @return 当前年
     */
    public int getYear() {
    	try {
    		return (new Integer(getYearString())).intValue();
    	}catch(Exception e) {}
    	return 0;
    }
    
    /**
     * 设置指定年份
     * @param year 年份值
     * @return 当前类实例
     * 2018年5月23日
     * @author MBG
     */
    public SDate setYear(String year) {
    	int yearInt; //整理后的年份值
    	try {
    		yearInt = Integer.valueOf(year);
    	}catch(Exception e) {
    		yearInt = 1000;
    	}
    	return setYear(yearInt);
    }
    
    /**
     * 设置指定年份
     * @param year 年份值
     * @return 当前类实例
     * 2018年5月23日
     * @author MBG
     */
    public SDate setYear(int year) {
    	if(year<1000) {
    		year = 1000;
    	}else if(year>9000) {
    		//为了防止设置月份值时溢出，设置最高年份为9000年
    		year = 9000;
    	}
    	setDateString(year+"-"+getMonthString()+"-"+getDayString()+" "+getOnlyTime());
    	return this;
    }
    
    /**
     * 返回当前年
     * @author 刘虻
     * 2008-7-2下午12:02:53
     * @return 当前年
     */
    public String getYearString() {
    	return getDate("yyyy");
    }
    
    
    /**
     * 获取年份数字
     * @author 刘虻
     * @return 年份数字
     * 2006-8-17  23:53:52
     */
    public int getDateYear() {
    	int reInt = 0;
    	try {
    		reInt = (new Integer(getDateYearString())).intValue();
    	}catch(Exception e) {}
    	return reInt;
    }
    
    /**
     * 获取后两位年份数字
     * @author 刘虻
     * @return 后两位年份数字
     * 2006-8-18  0:02:53
     */
    public int getDateShortYear() {
    	int reInt = 0;
    	try {
    		reInt = (new Integer(getDateShortYear())).intValue();
    	}catch(Exception e) {}
    	return reInt;
    }
    
    /**
     * 返回年份字符串
     * @author 刘虻
     * @return 年份字符串
     * 2006-8-18  0:01:21
     */
    public String getDateYearString() {
    	return getDate("yyyy");
    }
    
    /**
     * 返回年份后两位字符串
     * @author 刘虻
     * @return 年份后两位字符串
     * 2006-8-18  0:01:08
     */
    public String getDateShortYearString() {
    	return getDate("yy");
    }
    
    /**
     * 根据指定格式返回日期信息
     * @author 刘虻
     * @param dateFormat 指定的日期格式
     * @return 返回指定的日期字符串
     * 2006-8-17  23:59:40
     */
    public String getDate(String dateFormat) {
    	
    	//构造日期解析类
    	SimpleDateFormat simpleDateFormat = 
    				new SimpleDateFormat(dateFormat);
    	//返回解析后的日期字符串
    	return simpleDateFormat.format(getDate());
    }
    

    /**
     * 设置日期
     * @author 刘虻
     * @param dateStr 日期字符串
     * @param dateFormat 日期格式
     * @return 返回当前类实例
     * 2006-8-16  11:48:47
     */
    public SDate setDate(String dateStr,String dateFormat) {
        this.dateString = dateStr;
        doExcute(dateFormat); //执行解析
        return this;
    }

    
    /**
     * 设置日期对象
     * @author 刘虻
     * @param date 日期对象
     * @return 返回当前类实例
     * 2006-8-16  11:50:08
     */
    public SDate setDate(Date date) {
        this.date = date;
        doOut(null); //执行解析
        return this;
    }
    
    /**
     * 设置日期对象
     * @author 刘虻
     * @param date 日期对象
     * @param dateFormat 指定格式
     * @return 返回当前类实例
     * 2006-8-17  23:51:38
     */
    public SDate setDate(Date date,String dateFormat) {
        this.date = date;
        doOut(dateFormat); //执行解析
        return this;
    }
    
    /**
     * 返回日期对象
     * @author 刘虻
     * @return 日期对象
     * 2006-8-16  11:50:41
     */
    public Date getDate() {
        return this.date;
    }
    
    
    /**
     * 获得完整日期格式
     * @author 刘虻
     * @return 完整日期格式
     * 2006-8-16  11:56:15
     */
    public String getDateTime() {
        if (date==null) {
            date = new Date();
        }
        return (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")).format(this.date);
    }

    /**
     * 只获得日期字符串
     * @author 刘虻
     * @return 日期字符串
     * 2006-8-16  12:06:11
     */
    public String getOnlyDate() {
        if (date==null) {
            date = new Date();
        }
        return (new SimpleDateFormat("yyyy-MM-dd")).format(this.date);
    }
    
    
    /**
     * 只获得时间字符串
     * @author 刘虻
     * @return 时间字符串
     * 2006-8-16  12:07:43
     */
    public String getOnlyTime() {
        if (date==null) {
            date = new Date();
        }
        return (new SimpleDateFormat("HH:mm:ss")).format(this.date);
    }
    
    /**
     * 只获得月日字符串
     * @author 刘虻
     * 2008-9-5下午04:05:22
     * @return 月日字符串
     */
    public String getOnlyMonthDay() {
        if (date==null) {
            date = new Date();
        }
        return (new SimpleDateFormat("MM-dd")).format(this.date);
    }
    
    
    /**
     * 获取 年-月-日 小时:分
     * @author 刘虻
     * 2007-8-30下午03:02:18
     * @return 年-月-日 小时:分
     */
    public String getDateTimeWithoutSecond() {
        if (date==null) {
            date = new Date();
        }
        return (new SimpleDateFormat("yyyy-MM-dd HH:mm")).format(this.date);
    }
    

    /**
     * 获取日期对象
     * @author 刘虻
     * @param dateString 日期字符串
     * @return 日期对象
     * 2006-8-16  12:08:14
     */
    public static SDate valueOf(String dateString){
        return new SDate(dateString);
    }
    
    /**
     * 获取日期对象
     * @author 刘虻
     * 2007-7-6下午01:33:05
     * @param dateObj 日期信息
     * @return 日期对象
     */
    public static SDate valueOf(Object dateObj) {
    	return new SDate(dateObj);
    }
    
    
    /**
     * 获取整理后的日期字符串
     * @author 刘虻
     * 2007-7-31下午12:33:56
     * @param dateObj 整理前的日期信息
     * @return 整理后的日期字符串
     */
    public static String stringOf(Object dateObj) {
    	if (dateObj==null || "".equals(dateObj)) {
    		return "";
    	}
    	return valueOf(dateObj).getDateTime();
    }
    
    /**
     * 获得一共多少天
     * @author 刘虻
     * 2006-8-30上午10:39:47
     * @return 一共多少天
     */
    public long getDayLong() {
    	String dayStr = getOnlyDate();
    	return (new SDate(dayStr)).getHourLong() / 24;
    }
    
  
    
    /**
     * 获得当前总天数
     * @author 刘虻
     * 2006-8-30上午10:42:40
     * @return 当前总天数
     */
    public static long getNowDayLong() {
    	return (new SDate()).getDayLong();
    }
    
    /**
     * 获取当前总小时数
     * @author 刘虻
     * 2006-9-7下午12:12:08
     * @return 当前总小时数
     */
    public static long getNowHourLong() {
    	return (new SDate()).getHourLong();
    }
    
    public static int getNowYear() {
    	return (new SDate()).getYear();
    }
    
    /**
     * 获取当前总分钟数
     * @author 刘虻
     * 2006-9-7下午12:12:22
     * @return 当前总分钟数
     */
    public static long getNowMinuteLong() {
    	return (new SDate()).getMinuteLong();
    }
    
    /**
     * 获取当前总秒数
     * @author 刘虻
     * 2006-9-7下午12:12:34
     * @return 当前总秒数
     */
    public static long getNowSecondLong() {
    	return (new SDate()).getSecondLong();
    }
    
    /**
     * 获取当前总毫秒数
     * @author 刘虻
     * 2006-9-7下午12:12:46
     * @return 当前总毫秒数
     */
    public static long getNowMillisecond() {
    	return (new SDate()).getMillisecond();
    }
    
    /**
     * 将指定对象转换为毫秒值
     * @param dateObj 指定对象
     * @return        转换后的毫秒值
     * 2019年10月14日
     * @author MBG
     */
    public static long millisecondOf(Object dateObj) {
    	return new SDate(dateObj).getMillisecond();
    }
    
    /**
     * 获得一共多少秒
     * @author 刘虻
     * 2006-8-30上午10:37:27
     * @return 一共多少秒
     */
    public long getSecondLong() {
    	return getMillisecond() / 1000;
    }
    
    /**
     * 获得一共多少分钟
     * @author 刘虻
     * 2006-8-30上午10:38:09
     * @return 一共多少分钟
     */
    public long getMinuteLong() {
    	return getSecondLong() / 60;
    }
    
    /**
     * 获得一共多少小时
     * @author 刘虻
     * 2006-8-30上午10:38:42
     * @return 一共多少小时
     */
    public long getHourLong() {
    	return getMinuteLong() / 60;
    }
    
    /**
     * 将日期字符串按照格式转化为日期对象
     * @author 刘虻
     * @param dateString 日期字符串
     * @param dateFormat 日期格式
     * @return 日期对象
     * 2006-8-16  12:14:02
     */
    public static SDate valueOf(String dateString,String dateFormat) {
        return new SDate(dateString,dateFormat);
    }
    
    /**
     * 获取日期格式对象
     * @author 刘虻
     * 2006-9-11下午03:46:19
     * @param dateString 日期字符串
     * @return 日期对象
     */
    public static Date valueOfDate(String dateString) {
    	return (new SDate(dateString)).getDate();
    }
    
    
    /**
     * 将日期类型转换为String
     * @author 刘虻
     * @param date 日期类型
     * @return String日期
     * 2006-7-30  10:53:44
     */
    public static String stringDateTimeValueOf(Date date) {
        return (new SDate(date)).getDateTime();
    }
    
    
    /**
     * 整理日期字符串
     * @author 刘虻
     * @param dateString 源日期字符串
     * @return 整理后的字符串
     * 2006-8-18  18:46:57
     */
    public static String stringDateTimeValue(String dateString) {
    	return (new SDate(dateString)).getDateTime();
    }
    
    
    /**
     * 获取 年-月-日 小时:分
     * @author 刘虻
     * 2007-8-30下午03:12:07
     * @param dateString 日期对象
     * @return 年-月-日 小时:分
     */
    public static String stringDateTimeWithoutSecondValue(Object dateString) {
    	return (new SDate(dateString)).getDateTimeWithoutSecond();
    }
    
    /**
     * 获取当前时间的 年-月-日 小时:分
     * @author 刘虻
     * 2007-8-30下午03:13:10
     * @return 年-月-日 小时:分
     */
    public static String nowDateTimeWithoutSecond() {
    	return (new SDate()).getDateTimeWithoutSecond();
    }
    
    /**
     * 将日期字符串整理后返回单纯日期信息字符串
     * @author 刘虻
     * @param dateString 日期字符串
     * @return 单纯输出日期字符串
     * 2006-8-16  13:04:46
     */
    public static String stringDateValueOf(String dateString) {
        return (new SDate(dateString)).getOnlyDate();
    }

    /**
     * 获取日期字符串，如果输入的日期信息中不包含时间信息，则不输出时间信息
     * @author 刘虻
     * @param dateString 输入的日期信息
     * @return 输出整理后的日期信息
     * 2006-8-16  13:16:40
     */
    public static String getTitleValueOf(String dateString) {
       return (new SDate(dateString)).getDateString();
    }
   
    /**
     * 将日期字符串整理后返回单纯时间信息字符串
     * @author 刘虻
     * @param dateString 日期字符串
     * @return 单纯输出时间字符串
     * 2006-8-16  13:06:57
     */
    public static String stringTimeValueOf(String dateString) {
        return (new SDate(dateString)).getOnlyTime();
    }
    
    
    
    /**
     * 获得当前时间字符串 简称：dt
     * @author 刘虻
     * @return 当前日期时间字符串
     * 2006-7-30  10:54:48
     */
    public static String nowDateTimeString() {
        return SDate.stringDateTimeValueOf(new Date());
    }
    
    /**
     * 获得当前时间字符串 全称：nowDateTimeString
     * @return 当前日期时间字符串
     * 2016年10月17日
     * @author MBG
     */
    public static String dt() {
    	return SDate.stringDateTimeValueOf(new Date());
    }
    
    /**
     * 获取的当前紧凑型年月字符串
     * 刘虻
     * 2010-7-7 下午01:15:50
     * @return 当前紧凑型年月字符串
     */
    public static String nowYMString() {
    	return (new SDate()).getThinYMString();
    }

    /**
     * 获取当前日期  简称：d
     * @author 刘虻
     * 2007-5-31下午01:45:49
     * @return 当前日期 年-月-日
     */
    public static String nowDateString() {
    	return (new SDate()).getOnlyDate();
    }
    
    /**
     * 获取当前日期 远程：nowDateString
     * @return 当前日期  年-月-日
     * 2016年10月17日
     * @author MBG
     */
    public static String d() {
    	return (new SDate()).getOnlyDate();
    }
    
    
    /**
     * 获取缩减的当前日期 yyyyMMdd
     * @return 缩减的当前日期
     * 2016年6月7日
     * @author MBG
     */
    public static String nowThinDate() {
    	return (new SDate()).getThinYMDString();
    }
    
    /**
     * 获取当前时间  简称：t
     * @author 刘虻
     * 2007-5-31下午01:47:15
     * @return 当前时间  小时：分钟：秒
     */
    public static String nowTimeString() {
    	return (new SDate()).getOnlyTime();
    }
    
    /**
     * 获取当前时间 全称：nowTimeString
     * @return 当前时间   小时：分钟：秒
     * 2016年10月17日
     * @author MBG
     */
    public static String t() {
    	return (new SDate()).getOnlyTime();
    }

    /**
     * 将Date类型转换为SDate类型
     * @author 刘虻
     * @param date 日期
     * @return 封装后的日期
     * 2006-8-16  12:59:29
     */
    public static SDate valueOf(Date date) {
        return new SDate(date);
    }

    /**
     * 将字符串转为日期
     * @author 刘虻
     * @param dateString 日期字符串
     * @return 转换后的日期
     * 2006-8-17  23:24:55
     */
    public static Date dateValueOf(String dateString) {
    	return (new SDate(dateString)).getDate();
    }
    
    
    

    /**
     * 以当前对象作为时间点处理指定时间字段的增量
     * @author 刘虻
     * @param field 时间字段 字段值在Calendar类中的静态属性
     * @param amount 增量
     * @return 返回当前类实例
     * 2006-8-17  23:32:45
     */
    public SDate setApoint(int field,int amount) {

    	//构造日历对象
    	Calendar cd = getCalendar();
    	
    	//处理增量
    	cd.add(field,amount);
    	//设置处理后的值
    	setDate(cd.getTime());
    	return this;
    }
    
    /**
     * 设置月份增量
     * @author 刘虻
     * @param amount 月份增量
     * @return 返回当前类实例
     * 2006-8-18  0:15:43
     */
    public SDate setMonthApoint(int amount) {
    	//设置月份增量
    	setApoint(Calendar.MONTH,amount);
    	return this;
    }
    
    /**
     * 设置年份增量
     * @author 刘虻
     * @param amount 增量
     * @return 返回当前类实例
     * 2006-8-18  0:17:06
     */
    public SDate setYearApoint(int amount) {
    	//设置年份增量
    	setApoint(Calendar.YEAR,amount);
    	return this;
    }
    
    /**
     * 设置天增量
     * @author 刘虻
     * @param amount 增量
     * @return 返回当前类实例
     * 2006-8-18  0:19:00
     */
    public SDate setDayApoint(int amount) {
    	//设置天增量
    	setApoint(Calendar.DAY_OF_MONTH,amount);
    	return this;
    }
    
    /**
     * 设置小时增量
     * @author 刘虻
     * @param amount 小时增量
     * @return 返回当前类实例
     * 2006-8-18  0:19:44
     */
    public SDate setHourApoint(int amount) {
    	//设置小时增量
    	setApoint(Calendar.HOUR_OF_DAY,amount);
    	return this;
    }
    
    /**
     * 设置分钟增量
     * @author 刘虻
     * @param amount 增量
     * @return 返回当前类实例
     * 2006-8-18  0:20:41
     */
    public SDate setMinuteApoint(int amount) {
    	//设置分钟增量
    	setApoint(Calendar.MINUTE,amount);
    	return this;
    }
    
    
    /**
     * 设置秒增量
     * @author 刘虻
     * @param amount 秒增量
     * @return 返回当前类实例
     * 2006-8-18  0:21:38
     */
    public SDate setSecondApoint(int amount) {
    	//设置秒增量
    	setApoint(Calendar.SECOND,amount);
    	return this;
    }
    
    
    /**
     * 设置总秒时间
     * @author 刘虻
     * 2007-11-27上午10:22:20
     * @param second 总秒时间
     * @return 返回当前类实例
     */
    public SDate setAllSecond(long second) {
    	//变成毫秒
    	setMillisecond(second*1000);
    	return this;
    }
    
    /**
     * 获取总秒时间
     * @author 刘虻
     * 2007-11-27下午04:51:35
     * @return 总秒时间
     */
    public String getAllSecondString() {
    	return String.valueOf(getAllSecond());
    }
    
    /**
     * 获取总秒时间
     * @author 刘虻
     * 2007-11-27下午04:51:45
     * @return 总秒时间
     */
    public long getAllSecond() {
    	return getMillisecond()/1000;
    }
    
    /**
     * 获取日历对象
     * @author 刘虻
     * @return 日历对象
     * 2006-8-17  23:54:42
     */
    public Calendar getCalendar() {
    	//构造日历对象
    	Calendar cd = Calendar.getInstance();
    	//设置时间
    	cd.setTime(getDate());
    	
    	return cd;
    }
    

    /**
     * 以当前对象作为时间点处理指定时间字段的增量
     * @author 刘虻
     * @param dateStr 日期字符串
     * @param field 时间字段 字段值在Calendar类中的静态属性
     * @param amount 增量
     * @return 返回处理后的日期字符串
     * 2006-8-17  23:34:28
     */
    public static String toDate(
    		String dateStr,int field,int amount) {
    	//构造解析类
    	SDate sd = new SDate(dateStr);
    	//设置增量
    	sd.setApoint(field,amount);
    	//返回值
    	return sd.getDateString();
    }
    
    /**
     * 返回处理月份增量后的字符串
     * @author 刘虻
     * @param dateStr 原时间字符串
     * @param amount 增量
     * @return 处理后的字符串
     * 2006-8-18  0:23:27
     */
    public static String toDateMonth(String dateStr,int amount) {
    	return toDate(dateStr,Calendar.MONTH,amount);
    }
    
    
    /**
     * 返回处理天增量后的字符串
     * @author 刘虻
     * @param dateStr 原时间字符串
     * @param amount 增量
     * @return 处理后的字符串
     * 2006-8-18  0:24:39
     */
    public static String toDateDay(String dateStr,int amount) {
    	return toDate(dateStr,Calendar.DAY_OF_MONTH,amount);
    }
    


    /**
     * 获取设置值是否为日期值
     * @author 刘虻
     * 2007-5-31下午08:10:04
     * @return true是
     */
    public boolean isDate() {
        return isDate;
    }

    /**
     * 设置当前类中的值是否为日期值
     * @author 刘虻
     * 2007-5-31下午08:10:28
     * @param isDate true是
     * @return 当前类实例
     */
    public SDate setDate(boolean isDate) {
        this.isDate = isDate;
        return this;
    }
    
    
    /**
     * 返回时间字符串
     * @author 刘虻
     * 2007-3-5下午05:57:40
     * @return 时间字符串
     */
    public String getDateString() {
        return dateString;
    }

    /**
     * 设置时间字符串
     * @author 刘虻
     * 2007-3-5下午05:57:53
     * @param dateString 时间字符串
     * @return 返回当前类实例
     */
    public SDate setDateString(String dateString) {
        this.dateString = dateString;
        doExcute(null); //执行解析
        return this;
    }
    
    
    /**
     * 获取当前日期是当年的第几周
     * @author 刘虻
     * 2007-8-10下午03:34:19
     * @return 当前日期是当年的第几周
     */
    public int getWeekOfYear() {
    	if (getDayOfWeek()==7) {
    		return getCalendar().get(Calendar.WEEK_OF_YEAR)-1;
    	}
    	return getCalendar().get(Calendar.WEEK_OF_YEAR);
    }
    
    
    /**
     * 获取当前日期是本月的第几周
     * @author 刘虻
     * 2007-8-10下午03:37:31
     * @return 当前日期是本月的第几周
     */
    public int getWeekOfMonth() {
    	if (getDayOfWeek()==7) {
    		return getCalendar().get(Calendar.WEEK_OF_MONTH)-1;
    	}
    	return getCalendar().get(Calendar.WEEK_OF_MONTH);
    }

    
    /**
     * 返回当前日期是星期几  1 2 3 4 5 6 7（7为周日）
     * 
     * @author 刘虻
     * 2007-7-6下午01:27:39
     * @return 当前日期是星期几
     */
    public int getDayOfWeek() {
    	
    	int reWeek = getCalendar().get(Calendar.DAY_OF_WEEK);
    	
    	if (reWeek==1) {
    		return 7;
    	}
    	return reWeek-1;
    }
    
    /**
     * 测试入口
     * @author 刘虻
     * 2006-8-30上午10:35:39
     * @param arg0 导入参数
     */
    public static void main(String[] arg0) {
    	//毫秒值
    	long ms = SDate.millisecondOf("2019-10-14 16:56");
    	System.out.println(ms);
    	System.out.println(new SDate(ms).getDateTime());
    }
    
    
    /**
     * 获取指定时间序列号
     * @author 刘虻
     * 2008-4-23下午01:24:06
     * @return 指定时间序列号
     */
    public String getDateSid() {
    	//构造日期解析类
    	SimpleDateFormat sdf = new SimpleDateFormat("yyMMddHHmmssSSS");
    	return sdf.format(getDate());
    }
    
    /**
     * 获取指定时间戳
     * @author 刘虻
     * 2008-5-6下午03:30:55
     * @return 指定时间戳
     */
    public String getTS() {
    	return (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS")).format(getDate());
    }
    
    /**
     * 获取指定时间戳（紧凑格式）
     * @return 时间戳
     * 2017年4月23日
     * @author MBG
     */
    public String getThinTs() {
    	return (new SimpleDateFormat("yyyyMMddHHmmssSSS")).format(getDate());
    }
    
    /**
     * 获取时间序列号
     * @author 刘虻
     * 2007-8-31下午07:56:25
     * @return 时间序列号
     */
    public static String getNowDateSid() {
    	
    	//构造日期解析类
    	SimpleDateFormat sdf = new SimpleDateFormat("yyMMddHHmmssSSS");
    	
    	return sdf.format(new Date());
    }
    
    
    /**
     * 转换为数据库日期类型
     * @author 刘虻
     * 2006-9-11下午03:51:35
     * @param dateString 日期字符串
     * @return 数据库日期类型
     */
    public static java.sql.Date valueOfSqlDate(String dateString){
    	return (new SDate(dateString)).getSqlDate();
    }
    
    /**
     * 获取数据库提交的日期对象
     * @author 刘虻
     * 2006-9-11下午03:50:24
     * @return 数据库提交的日期对象
     */
    public java.sql.Date getSqlDate(){
    	java.sql.Date sqlDate = new java.sql.Date(getMillisecond());
    	return sqlDate;
    }
    
    
    
    /**
     * 获取当前时间中，一天开始的时间，比如 2007-01-01 12:20:20 对象
     * 返回值是 2007-01-01 00:00:00
     * @author 刘虻
     * 2007-7-9上午10:26:06
     * @return 一天开始的时间
     */
    public String getDayStartString() {
    	
    	//获取当前时间字符串
    	String dateStr = getDateString();

    	return dateStr.substring(0,dateStr.indexOf(" "))+" 00:00:00";
    }
    
    
    /**
     * 获取当前时间中，一天结束的时间，比如 2007-01-01 12:20:20 对象
     * 返回值是 2007-01-01 23:59:59
     * @author 刘虻
     * 2007-7-9上午10:27:10
     * @return 一天结束的时间
     */
    public String getDayEndString() {
    	
    	//获取当前时间字符串
    	String dateStr = getDateString();

    	return dateStr.substring(0,dateStr.indexOf(" "))+" 23:59:59";
    }
    
	
	/**
	 * 获取紧凑年月字符串
	 * 刘虻
	 * 2010-7-7 下午01:13:26
	 * @return 紧凑年月字符串
	 */
	public String getThinYMString() {
    	//构造日期解析类
    	SimpleDateFormat sdf = new SimpleDateFormat("yyyyMM");
		return  sdf.format(date);
	}
	
	
	/**
	 * 获取紧凑的年月日字符串
	 * @author 刘虻
	 * 2007-9-5下午12:55:25
	 * @return 紧凑的年月日字符串
	 */
	public String getThinYMDString() {
    //构造日期解析类
    SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
		return  sdf.format(date);
	}

  /**
   * 返回yyyy字符串
   */
  public String getYYYY(){
    //构造日期解析类
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy");
		return  sdf.format(date);
  }

  /**
   * 返回yy字符串
   */
  public String getYY(){
    //构造日期解析类
    SimpleDateFormat sdf = new SimpleDateFormat("yy");
		return  sdf.format(date);
  }
	
  /**
   * 返回yyyymm字符串
   */
  public String getYYYYMM(){
    //构造日期解析类
    SimpleDateFormat sdf = new SimpleDateFormat("yyyyMM");
		return  sdf.format(date);
  }

  /**
   * 返回yyyymm字符串
   */
  public String getYYMM(){
    //构造日期解析类
    SimpleDateFormat sdf = new SimpleDateFormat("yyMM");
		return  sdf.format(date);
  }

  /**
   * 返回yyyyMMdd字符串
   */
  public String getYYYYMMDD(){
    //构造日期解析类
    SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
		return  sdf.format(date);
  }

  /**
   * 返回yyMMdd字符串
   */
  public String getYYMMDD(){
    //构造日期解析类
    SimpleDateFormat sdf = new SimpleDateFormat("yyMMdd");
		return  sdf.format(date);
  }
	
	/**
	 * 获取两位年的紧凑的年月日字符串
	 * @author 刘虻
	 * 2007-9-5下午12:55:42
	 * @return 两位年的紧凑的年月日字符串
	 */
	public String getShortThinYMDString() {
    	//构造日期解析类
    	SimpleDateFormat sdf = new SimpleDateFormat("yyMMdd");
    	
		return  sdf.format(date);
	}
	
	/**
	 * 获取指定格式的日期字符串
	 * @param formatStr 格式字符串
	 * @return 指定格式的日期字符串
	 * 2019年3月11日
	 * @author MBG
	 */
	public String format(String formatStr) {
    	//构造日期解析类
    	SimpleDateFormat sdf = new SimpleDateFormat(formatStr);
		return  sdf.format(date);
	}
	
	/**
	 * 通过毫秒获取时间
	 * @author 刘虻
	 * 2007-3-25下午07:01:47
	 * @param millisecond 毫秒
	 * @return 时间字符串
	 */
	public static String getDateFromMillisecond(long millisecond) {
		return (new SDate(millisecond)).getDateString();
	}
	
	
	/**
	 * 第一个时间减去第二个时间的毫秒值
	 * @author 刘虻
	 * 2007-6-1下午01:29:08
	 * @param dataSrc 第一个时间
	 * @param dataSub 第二个时间
	 * @return 毫秒差值
	 */
	public static long subtractDateReturnMillisecond(String dataSrc,String dataSub) {
		return (new SDate(dataSrc)).getMillisecond()-(new SDate(dataSub)).getMillisecond();
	}
	
	
	/**
	 * 第一个时间减去第二个时间的秒值
	 * @author 刘虻
	 * 2007-6-1下午01:29:08
	 * @param dataSrc 第一个时间
	 * @param dataSub 第二个时间
	 * @return 秒差值
	 */
	public static long subtractDateReturnSecond(String dataSrc,String dataSub) {
		return (new SDate(dataSrc)).getSecondLong()-(new SDate(dataSub)).getSecondLong();
	}
	
	/**
	 * 第一个时间减去第二个时间的分钟值
	 * @author 刘虻
	 * 2007-6-1下午01:29:08
	 * @param dataSrc 第一个时间
	 * @param dataSub 第二个时间
	 * @return 分钟差值
	 */
	public static long subtractDateReturnMinute(String dataSrc,String dataSub) {
		return (new SDate(dataSrc)).getMinuteLong()-(new SDate(dataSub)).getMinuteLong();
	}
	
	
	/**
	 * 第一个时间减去第二个时间的小时值
	 * @author 刘虻
	 * 2007-6-1下午01:29:08
	 * @param dataSrc 第一个时间
	 * @param dataSub 第二个时间
	 * @return 小时差值
	 */
	public static long subtractDateReturnHour(String dataSrc,String dataSub) {
		return (new SDate(dataSrc)).getHourLong()-(new SDate(dataSub)).getHourLong();
	}
	
	
	/**
	 * 第一个时间减去第二个时间的天值
	 * @author 刘虻
	 * 2007-6-1下午01:29:08
	 * @param dataSrc 第一个时间
	 * @param dataSub 第二个时间
	 * @return 天差值
	 */
	public static long subtractDateReturnDay(String dataSrc,String dataSub) {
		return (new SDate(dataSrc)).getDayLong()-(new SDate(dataSub)).getDayLong();
	}
	
	/**
	 * 是否比目标值大
	 * @author 刘虻
	 * 2007-7-3下午06:58:46
	 * @param otherDate 目标值
	 * @return true比目标值大
	 */
	public boolean moreThan(SDate otherDate) {
		if (otherDate==null) {
			return true;
		}
		return getMillisecond() > otherDate.getMillisecond();
	}
	
	
	/**
	 * 是否比目标值大
	 * @author 刘虻
	 * 2007-7-3下午06:58:46
	 * @param otherDateObj 目标值
	 * @return true比目标值大
	 */
	public boolean moreThan(Object otherDateObj) {
		
		//构造目标值
		SDate otherSDate = new SDate();
		otherSDate.setDate(otherDateObj);
		return moreThan(otherSDate);
	}
	
	/**
	 * 当前对象时间是否比指定时间大
	 * @param timeStr 指定时间  hh:mm:ss  或  hh:mm 或 hh
	 * @return 是否比指定时间大
	 * 2015年3月24日
	 * @author 马宝刚
	 */
	public boolean timeMoreThan(String timeStr) {
	    if(timeStr==null) {
	        return false;
	    }
	    timeStr = timeStr.trim();
	    int len = timeStr.length(); //字符长度
	    if(len<1) {
	        return false;
	    }
	    if(len>4) {
	        return moreThan(getOnlyDate()+" "+timeStr);
	    }else if(len>2) {
	        return moreThan((getOnlyDate()+" "+timeStr+":00"));
	    }else {
	        return moreThan(getOnlyDate()+" "+timeStr+":00:00");
	    }
	}
	
	   /**
     * 当前时间是否比指定时间大
     * @param timeStr 指定时间  hh:mm:ss  或  hh:mm 或 hh
     * @return 是否比指定时间大
     * 2015年3月24日
     * @author 马宝刚
     */
	public static boolean timeMoreThanNow(String timeStr) {
	    return (new SDate()).timeMoreThan(timeStr);
	}
	
	/**
	 * 是否比目标值大
	 * @author 刘虻
	 * 2007-7-3下午06:58:46
	 * @param otherDateStr 目标值
	 * @return true比目标值大
	 */
	public boolean moreThan(String otherDateStr) {
		return moreThan(new SDate(otherDateStr));
	}
	
	/**
	 * 是否比当前时间大
	 * @author 刘虻
	 * 2007-7-3下午07:12:27
	 * @return true比当前时间大
	 */
	public  boolean moreThanNow() {
		return moreThan(new SDate());
	}
	
	/**
	 * 是否比当日0点大
	 * @return 比当日0点大
	 * 2018年11月21日
	 * @author MBG
	 */
	public boolean morethanToday() {
		return moreThan(SDate.nowDateString()+" 00:00:00");
	}
	
	/**
	 * 指定日期是否比当前时间大
	 * @param dateObj 日期，可以为 Date   String  格式为 yyyy-MM-dd hh:mm:ss
	 * @return 指定日期是否比当前时间大
	 * 2015年3月24日
	 * @author 马宝刚
	 */
	public static boolean moreThanNow(Object dateObj) {
	    return (new SDate(dateObj)).moreThanNow();
	}
	
	/**
	 * 指定日期是否比当日0点大
	 * @param dateObj dateObj 日期，可以为 Date   String  格式为 yyyy-MM-dd hh:mm:ss
	 * @return 指定日期是否比当日0点大
	 * 2018年11月21日
	 * @author MBG
	 */
	public static boolean moreThanToday(Object dateObj) {
		return (new SDate(dateObj)).morethanToday();
	}
	
	
	/**
	 * 获取时间戳字符串 简称：ts
	 * @author 刘虻
	 * 2007-10-16下午08:40:41
	 * @return 时间戳字符串
	 */
	public static String getNowTS() {
    	return (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS")).format(new Date());
	}
	
	
	/**
	 * 获取时间排成的字符串
	 * @return 时间排成的字符串
	 * 2016年12月19日
	 * @author MBG
	 */
	public static String sn() {
		return (new SimpleDateFormat("yyMMddHHmmss")).format(new Date());
	}
	
	/**
	 * 获取时间戳字符串 全称：getNowTS
	 * @return
	 * 2016年10月17日
	 * @author MBG
	 */
	public static String ts() {
		return (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS")).format(new Date());
	}
	
	/**
	 * 获取时间戳字符串 （紧凑格式）
	 * @return
	 * 2016年10月17日
	 * @author MBG
	 */
	public static String thinTs() {
		return (new SimpleDateFormat("yyyyMMddHHmmssSSS")).format(new Date());
	}
	
	/**
	 * 将毫秒时间转换为时间戳
	 * @param tsLong 毫秒时间
	 * @return 时间戳信息
	 * 2016年9月18日
	 * @author MBG
	 */
	public static String getTs(long tsLong) {
		if(tsLong<1) {
			return "";
		}
		return (new SDate(tsLong)).getTS();
	}
	
	/**
	 * 将毫秒值转换为可视化的值
	 * @author 刘虻
	 * 2008-5-6下午03:20:48
	 * @param millisecode 毫秒值
	 * @return 可视化的值
	 */
	public static String showMillisecond(long millisecode) {
		long day  = 0; //天
		long hour = 0; //小时
		long min  = 0; //分钟
		long sec  = 0; //秒
		if(millisecode>=MILLISECONDS_OF_DAY) {
			day         = millisecode/MILLISECONDS_OF_DAY;
			millisecode = millisecode - MILLISECONDS_OF_DAY*day;
		}
		if (millisecode>=MILLISECONDS_OF_HOUR) {
			hour        = millisecode/MILLISECONDS_OF_HOUR;
			millisecode = millisecode - MILLISECONDS_OF_HOUR*hour;
		}
		if (millisecode>=MILLISECONDS_OF_MINUTE) {
			min         = millisecode/MILLISECONDS_OF_MINUTE;
			millisecode = millisecode - MILLISECONDS_OF_MINUTE*min;
		}
		if (millisecode>=MILLISECONDS_OF_SECOND) {
			sec         = millisecode/MILLISECONDS_OF_SECOND;
			millisecode = millisecode - MILLISECONDS_OF_SECOND*sec;
		}
		//构建返回值
		StringBuffer reSbf = new StringBuffer();
		if(day>0) {
			reSbf.append(day).append("d ");
		}
		if(hour>0) {
			reSbf.append(hour).append("h ");
		}
		if(min>0) {
			reSbf.append(min).append("m ");
		}
		if(sec>0) {
			reSbf.append(sec).append("s ");
		}
		return reSbf.append(millisecode).append("ms").toString();
	}
	
	/**
	 * 返回当前周的汉字信息
	 * @return 当前周的汉字信息
	 * 2019年5月23日
	 * @author MBG
	 */
	public String titleWeek() {
		int week = getDayOfWeek();
		switch(week) {
			case 1:
				return "星期一";
			case 2:
				return "星期二";
			case 3:
				return "星期三";
			case 4:
				return "星期四";
			case 5:
				return "星期五";
			case 6:
				return "星期六";
			case 7:
				return "星期日";
		}
		return "";
	}
	
	/**
	 * 覆盖方法
	 * @author 刘虻
	 * 2007-5-22上午10:28:44
	 */
	@Override
    public Object clone() {
		//构建返回值
		SDate sd = new SDate();
		sd.date = date;
		sd.dateString = dateString;
		sd.isDate = isDate;
		return sd;
	}
	
	/**
	 * 克隆
	 * @return 同样的日期时间处理类，不同实例
	 * 2019年6月20日
	 * @author MBG
	 */
	public SDate cn() {
		//构建返回值
		SDate sd = new SDate();
		sd.date = date;
		sd.dateString = dateString;
		sd.isDate = isDate;
		return sd;
	}
	
	/**
	 * 返回当前月总共多少天
	 * @author 刘虻
	 * 2008-7-2上午11:59:43
	 * @return 当前月总共多少天
	 */
	public int getMonthDay() {
		//获取当前月
		int month = getMonth();
		
		switch(month) {
			case 1: return 31;
			case 2: 
				if (getYear()==365) {
					return 28;
				}
				return 29;
			case 3: return 31;
			case 4: return 30;
			case 5: return 31;
			case 6: return 30;
			case 7: return 31;
			case 8: return 31;
			case 9: return 30;
			case 10: return 31;
			case 11: return 30;
			case 12: return 31;
		}
		return 30;
	}
	
	/**
	 * 返回当前年一共多少天
	 * @author 刘虻
	 * 2008-7-2下午12:00:13
	 * @return 当前年一共多少天
	 */
	public int getYearDay() {
		//返回当前年
		int year = getYear();
		if (year%400==0 || (year%4==0 && year%100!=0)) {
			return 366;
		}
		return 365;
	}
	
	/**
	 * 返回年初到当前天一共多少天
	 * @author 刘虻
	 * 2008-7-2下午12:01:05
	 * @return 年初到当前天一共多少天
	 */
	public int getFromYearDay() {
		//获取当前天
		int day = getDay();
		//获取当前月的前一月
		int month = getMonth();
		switch(month) {
			case 1: day += 0; break;
			case 2: day += 31; break;
			case 3: day += 59; break;
			case 4: day += 90; break;
			case 5: day += 120; break;
			case 6: day += 151; break;
			case 7: day += 181; break;
			case 8: day += 212; break;
			case 9: day += 243; break;
			case 10: day += 273; break;
			case 11: day += 304; break;
			case 12: day += 334; break;
		}
		if (month<3 && getYearDay()==366) {
			day++;
		}
		return day;
	}
    
	   /**
     * 按照指定格式输出
     * @param format 指定时间格式
     * @return 按照指定时间格式输出字符串
     * 2014年12月11日
     * @author 马宝刚
     */
    public String formatDate(String format) {
        return (new SimpleDateFormat(format)).format(getDate());
    }
    
       /**
     * 按照指定格式输出
     * @param dateObj 时间数据值
     * @param format 指定时间格式
     * @return 按照指定时间格式输出字符串
     * 2014年12月11日
     * @author 马宝刚
     */
    public static String formatDate(Object dateObj,String format) {
        return (new SDate(dateObj)).formatDate(format);
    }
    
    /**
     * 返回当前时间所在月份第一天的日期
     * @return  YYYY-MM-01
     * 2016年8月1日
     * @author MBG
     */
    public String getBeginDateOfMonth() {
    	return getDate("yyyy")+"-"+getDate("MM")+"-01";
    }
    
    /**
     * 返回当前时间所在月份的最后一个日期
     * @return YYYY-MM-DD
     * 2016年8月1日
     * @author MBG
     */
    public String getLastDateOfMonth() {
    	return getDate("yyyy")+"-"+getDate("MM")+"-"+getLastDayOfMonth();
    }
    
    
    
    /**
     * 返回当前时间所在月份最后一天
     * @return DD
     * 2016年8月1日
     * @author MBG
     */
    public String getLastDayOfMonth() {
    	return (new SDate(getBeginDateOfMonth())).setMonthApoint(1).setDayApoint(-1).getDayString();
    }
    
    /**
     * 覆盖方法
     */
    @Override
    public String toString() {
        return getTS();
    }
    
    /**
     * 当前日期所在的星期是否为当月的最后一个星期 （即，下个星期的这个星期几，已经在下个月）
     * @return 当前日期所在的星期是否为当月的最后一个星期
     * 2018年6月16日
     * @author MBG
     */
    public boolean isLastWeek() {
		return getMonth() != ((SDate) clone()).setDayApoint(7).getMonth();
	}
    
    
    /**
     * 获取指定月份，末尾指定周几是几号
     * @param week     指定月末周几，比如18年6月的最后一个周五
     * @param month    指定月份
     * @param year     指定月份所在的年份
     * @return         指定月份最后周几是几号
     * 2018年6月16日
     * @author MBG
     */
    public static int getMonthLastWeekDay(int week,int month,int year) {
    	month++;
    	if(month>12) {
    		month = 1;
    		year++;
    	}
    	if(week==0) {
    		week = 7;
    	}else if(week<0) {
    		week = 1;
    	}else if(week>7) {
    		week = 7;
    	}
    	//构建下个月的1号
    	SDate date = new SDate((year<100?("20"+year):year)+"-"+(month<10?("0"+month):month)+"-01");
    	date.setDayApoint(-1); //减一天，为当月末尾天
    	while(date.getDayOfWeek()!=week) {
    		date.setDayApoint(-1);
    	}
    	return date.getDay();
    }
    
    
	/**
	 * 获取解析后的时间信息
	 * @return 解析后的运行时间信息
	 * 2016年6月29日
	 * @author MBG
	 */
	public static String runTimeInfo(long runTime) {
		if(runTime<1000) {
			return runTime+" ms";
		}
		//余数
		long ys = runTime % 1000;
		runTime = runTime / 1000;
		if(runTime<60) {
			return runTime+"."+ys+" s";
		}
		ys = runTime % 60;
		runTime = runTime /60;
		if(runTime<60) {
			return runTime+" m "+ys+" s";
		}
		ys = runTime % 60;
		runTime = runTime /60;
		if(runTime<24) {
			return runTime+" h "+ys+" m";
		}
		ys = runTime % 24;
		runTime = runTime/24;
		return runTime+" d "+ys+" h";
	}
}
